(function () {
    // lib/handlebars/base.js
    var Handlebars = {};

    Handlebars.VERSION = "1.0.beta.6";

    Handlebars.helpers = {};
    Handlebars.partials = {};

    Handlebars.registerHelper = function (name, fn, inverse) {
        if (inverse) { fn.not = inverse; }
        this.helpers[name] = fn;
    };

    Handlebars.registerPartial = function (name, str) {
        this.partials[name] = str;
    };

    Handlebars.registerHelper('helperMissing', function (arg) {
        if (arguments.length === 2) {
            return undefined;
        } else {
            throw new Error("Could not find property '" + arg + "'");
        }
    });

    var toString = Object.prototype.toString, functionType = "[object Function]";

    Handlebars.registerHelper('blockHelperMissing', function (context, options) {
        var inverse = options.inverse || function () { }, fn = options.fn;


        var ret = "";
        var type = toString.call(context);

        if (type === functionType) { context = context.call(this); }

        if (context === true) {
            return fn(this);
        } else if (context === false || context == null) {
            return inverse(this);
        } else if (type === "[object Array]") {
            if (context.length > 0) {
                for (var i = 0, j = context.length; i < j; i++) {
                    ret = ret + fn(context[i]);
                }
            } else {
                ret = inverse(this);
            }
            return ret;
        } else {
            return fn(context);
        }
    });

    Handlebars.registerHelper('each', function (context, options) {
        var fn = options.fn, inverse = options.inverse;
        var ret = "";

        if (context && context.length > 0) {
            for (var i = 0, j = context.length; i < j; i++) {
                ret = ret + fn(context[i]);
            }
        } else {
            ret = inverse(this);
        }
        return ret;
    });

    Handlebars.registerHelper('if', function (context, options) {
        var type = toString.call(context);
        if (type === functionType) { context = context.call(this); }

        if (!context || Handlebars.Utils.isEmpty(context)) {
            return options.inverse(this);
        } else {
            return options.fn(this);
        }
    });

    Handlebars.registerHelper('unless', function (context, options) {
        var fn = options.fn, inverse = options.inverse;
        options.fn = inverse;
        options.inverse = fn;

        return Handlebars.helpers['if'].call(this, context, options);
    });

    Handlebars.registerHelper('with', function (context, options) {
        return options.fn(context);
    });

    Handlebars.registerHelper('log', function (context) {
        Handlebars.log(context);
    });
    ;
    //>>excludeStart('excludeHbsParser', pragmas.excludeHbsParser)
    // lib/handlebars/compiler/parser.js
    /* Jison generated parser */
    var handlebars = (function () {

        var parser = { trace: function trace() { },
            yy: {},
            symbols_: { "error": 2, "root": 3, "program": 4, "EOF": 5, "statements": 6, "simpleInverse": 7, "statement": 8, "openInverse": 9, "closeBlock": 10, "openBlock": 11, "mustache": 12, "partial": 13, "CONTENT": 14, "COMMENT": 15, "OPEN_BLOCK": 16, "inMustache": 17, "CLOSE": 18, "OPEN_INVERSE": 19, "OPEN_ENDBLOCK": 20, "path": 21, "OPEN": 22, "OPEN_UNESCAPED": 23, "OPEN_PARTIAL": 24, "params": 25, "hash": 26, "param": 27, "STRING": 28, "INTEGER": 29, "BOOLEAN": 30, "hashSegments": 31, "hashSegment": 32, "ID": 33, "EQUALS": 34, "pathSegments": 35, "SEP": 36, "$accept": 0, "$end": 1 },
            terminals_: { 2: "error", 5: "EOF", 14: "CONTENT", 15: "COMMENT", 16: "OPEN_BLOCK", 18: "CLOSE", 19: "OPEN_INVERSE", 20: "OPEN_ENDBLOCK", 22: "OPEN", 23: "OPEN_UNESCAPED", 24: "OPEN_PARTIAL", 28: "STRING", 29: "INTEGER", 30: "BOOLEAN", 33: "ID", 34: "EQUALS", 36: "SEP" },
            productions_: [0, [3, 2], [4, 3], [4, 1], [4, 0], [6, 1], [6, 2], [8, 3], [8, 3], [8, 1], [8, 1], [8, 1], [8, 1], [11, 3], [9, 3], [10, 3], [12, 3], [12, 3], [13, 3], [13, 4], [7, 2], [17, 3], [17, 2], [17, 2], [17, 1], [25, 2], [25, 1], [27, 1], [27, 1], [27, 1], [27, 1], [26, 1], [31, 2], [31, 1], [32, 3], [32, 3], [32, 3], [32, 3], [21, 1], [35, 3], [35, 1]],
            performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$) {

                var $0 = $$.length - 1;
                switch (yystate) {
                    case 1: return $$[$0 - 1]
                        break;
                    case 2: this.$ = new yy.ProgramNode($$[$0 - 2], $$[$0])
                        break;
                    case 3: this.$ = new yy.ProgramNode($$[$0])
                        break;
                    case 4: this.$ = new yy.ProgramNode([])
                        break;
                    case 5: this.$ = [$$[$0]]
                        break;
                    case 6: $$[$0 - 1].push($$[$0]); this.$ = $$[$0 - 1]
                        break;
                    case 7: this.$ = new yy.InverseNode($$[$0 - 2], $$[$0 - 1], $$[$0])
                        break;
                    case 8: this.$ = new yy.BlockNode($$[$0 - 2], $$[$0 - 1], $$[$0])
                        break;
                    case 9: this.$ = $$[$0]
                        break;
                    case 10: this.$ = $$[$0]
                        break;
                    case 11: this.$ = new yy.ContentNode($$[$0])
                        break;
                    case 12: this.$ = new yy.CommentNode($$[$0])
                        break;
                    case 13: this.$ = new yy.MustacheNode($$[$0 - 1][0], $$[$0 - 1][1])
                        break;
                    case 14: this.$ = new yy.MustacheNode($$[$0 - 1][0], $$[$0 - 1][1])
                        break;
                    case 15: this.$ = $$[$0 - 1]
                        break;
                    case 16: this.$ = new yy.MustacheNode($$[$0 - 1][0], $$[$0 - 1][1])
                        break;
                    case 17: this.$ = new yy.MustacheNode($$[$0 - 1][0], $$[$0 - 1][1], true)
                        break;
                    case 18: this.$ = new yy.PartialNode($$[$0 - 1])
                        break;
                    case 19: this.$ = new yy.PartialNode($$[$0 - 2], $$[$0 - 1])
                        break;
                    case 20:
                        break;
                    case 21: this.$ = [[$$[$0 - 2]].concat($$[$0 - 1]), $$[$0]]
                        break;
                    case 22: this.$ = [[$$[$0 - 1]].concat($$[$0]), null]
                        break;
                    case 23: this.$ = [[$$[$0 - 1]], $$[$0]]
                        break;
                    case 24: this.$ = [[$$[$0]], null]
                        break;
                    case 25: $$[$0 - 1].push($$[$0]); this.$ = $$[$0 - 1];
                        break;
                    case 26: this.$ = [$$[$0]]
                        break;
                    case 27: this.$ = $$[$0]
                        break;
                    case 28: this.$ = new yy.StringNode($$[$0])
                        break;
                    case 29: this.$ = new yy.IntegerNode($$[$0])
                        break;
                    case 30: this.$ = new yy.BooleanNode($$[$0])
                        break;
                    case 31: this.$ = new yy.HashNode($$[$0])
                        break;
                    case 32: $$[$0 - 1].push($$[$0]); this.$ = $$[$0 - 1]
                        break;
                    case 33: this.$ = [$$[$0]]
                        break;
                    case 34: this.$ = [$$[$0 - 2], $$[$0]]
                        break;
                    case 35: this.$ = [$$[$0 - 2], new yy.StringNode($$[$0])]
                        break;
                    case 36: this.$ = [$$[$0 - 2], new yy.IntegerNode($$[$0])]
                        break;
                    case 37: this.$ = [$$[$0 - 2], new yy.BooleanNode($$[$0])]
                        break;
                    case 38: this.$ = new yy.IdNode($$[$0])
                        break;
                    case 39: $$[$0 - 2].push($$[$0]); this.$ = $$[$0 - 2];
                        break;
                    case 40: this.$ = [$$[$0]]
                        break;
                }
            },
            table: [{ 3: 1, 4: 2, 5: [2, 4], 6: 3, 8: 4, 9: 5, 11: 6, 12: 7, 13: 8, 14: [1, 9], 15: [1, 10], 16: [1, 12], 19: [1, 11], 22: [1, 13], 23: [1, 14], 24: [1, 15] }, { 1: [3] }, { 5: [1, 16] }, { 5: [2, 3], 7: 17, 8: 18, 9: 5, 11: 6, 12: 7, 13: 8, 14: [1, 9], 15: [1, 10], 16: [1, 12], 19: [1, 19], 20: [2, 3], 22: [1, 13], 23: [1, 14], 24: [1, 15] }, { 5: [2, 5], 14: [2, 5], 15: [2, 5], 16: [2, 5], 19: [2, 5], 20: [2, 5], 22: [2, 5], 23: [2, 5], 24: [2, 5] }, { 4: 20, 6: 3, 8: 4, 9: 5, 11: 6, 12: 7, 13: 8, 14: [1, 9], 15: [1, 10], 16: [1, 12], 19: [1, 11], 20: [2, 4], 22: [1, 13], 23: [1, 14], 24: [1, 15] }, { 4: 21, 6: 3, 8: 4, 9: 5, 11: 6, 12: 7, 13: 8, 14: [1, 9], 15: [1, 10], 16: [1, 12], 19: [1, 11], 20: [2, 4], 22: [1, 13], 23: [1, 14], 24: [1, 15] }, { 5: [2, 9], 14: [2, 9], 15: [2, 9], 16: [2, 9], 19: [2, 9], 20: [2, 9], 22: [2, 9], 23: [2, 9], 24: [2, 9] }, { 5: [2, 10], 14: [2, 10], 15: [2, 10], 16: [2, 10], 19: [2, 10], 20: [2, 10], 22: [2, 10], 23: [2, 10], 24: [2, 10] }, { 5: [2, 11], 14: [2, 11], 15: [2, 11], 16: [2, 11], 19: [2, 11], 20: [2, 11], 22: [2, 11], 23: [2, 11], 24: [2, 11] }, { 5: [2, 12], 14: [2, 12], 15: [2, 12], 16: [2, 12], 19: [2, 12], 20: [2, 12], 22: [2, 12], 23: [2, 12], 24: [2, 12] }, { 17: 22, 21: 23, 33: [1, 25], 35: 24 }, { 17: 26, 21: 23, 33: [1, 25], 35: 24 }, { 17: 27, 21: 23, 33: [1, 25], 35: 24 }, { 17: 28, 21: 23, 33: [1, 25], 35: 24 }, { 21: 29, 33: [1, 25], 35: 24 }, { 1: [2, 1] }, { 6: 30, 8: 4, 9: 5, 11: 6, 12: 7, 13: 8, 14: [1, 9], 15: [1, 10], 16: [1, 12], 19: [1, 11], 22: [1, 13], 23: [1, 14], 24: [1, 15] }, { 5: [2, 6], 14: [2, 6], 15: [2, 6], 16: [2, 6], 19: [2, 6], 20: [2, 6], 22: [2, 6], 23: [2, 6], 24: [2, 6] }, { 17: 22, 18: [1, 31], 21: 23, 33: [1, 25], 35: 24 }, { 10: 32, 20: [1, 33] }, { 10: 34, 20: [1, 33] }, { 18: [1, 35] }, { 18: [2, 24], 21: 40, 25: 36, 26: 37, 27: 38, 28: [1, 41], 29: [1, 42], 30: [1, 43], 31: 39, 32: 44, 33: [1, 45], 35: 24 }, { 18: [2, 38], 28: [2, 38], 29: [2, 38], 30: [2, 38], 33: [2, 38], 36: [1, 46] }, { 18: [2, 40], 28: [2, 40], 29: [2, 40], 30: [2, 40], 33: [2, 40], 36: [2, 40] }, { 18: [1, 47] }, { 18: [1, 48] }, { 18: [1, 49] }, { 18: [1, 50], 21: 51, 33: [1, 25], 35: 24 }, { 5: [2, 2], 8: 18, 9: 5, 11: 6, 12: 7, 13: 8, 14: [1, 9], 15: [1, 10], 16: [1, 12], 19: [1, 11], 20: [2, 2], 22: [1, 13], 23: [1, 14], 24: [1, 15] }, { 14: [2, 20], 15: [2, 20], 16: [2, 20], 19: [2, 20], 22: [2, 20], 23: [2, 20], 24: [2, 20] }, { 5: [2, 7], 14: [2, 7], 15: [2, 7], 16: [2, 7], 19: [2, 7], 20: [2, 7], 22: [2, 7], 23: [2, 7], 24: [2, 7] }, { 21: 52, 33: [1, 25], 35: 24 }, { 5: [2, 8], 14: [2, 8], 15: [2, 8], 16: [2, 8], 19: [2, 8], 20: [2, 8], 22: [2, 8], 23: [2, 8], 24: [2, 8] }, { 14: [2, 14], 15: [2, 14], 16: [2, 14], 19: [2, 14], 20: [2, 14], 22: [2, 14], 23: [2, 14], 24: [2, 14] }, { 18: [2, 22], 21: 40, 26: 53, 27: 54, 28: [1, 41], 29: [1, 42], 30: [1, 43], 31: 39, 32: 44, 33: [1, 45], 35: 24 }, { 18: [2, 23] }, { 18: [2, 26], 28: [2, 26], 29: [2, 26], 30: [2, 26], 33: [2, 26] }, { 18: [2, 31], 32: 55, 33: [1, 56] }, { 18: [2, 27], 28: [2, 27], 29: [2, 27], 30: [2, 27], 33: [2, 27] }, { 18: [2, 28], 28: [2, 28], 29: [2, 28], 30: [2, 28], 33: [2, 28] }, { 18: [2, 29], 28: [2, 29], 29: [2, 29], 30: [2, 29], 33: [2, 29] }, { 18: [2, 30], 28: [2, 30], 29: [2, 30], 30: [2, 30], 33: [2, 30] }, { 18: [2, 33], 33: [2, 33] }, { 18: [2, 40], 28: [2, 40], 29: [2, 40], 30: [2, 40], 33: [2, 40], 34: [1, 57], 36: [2, 40] }, { 33: [1, 58] }, { 14: [2, 13], 15: [2, 13], 16: [2, 13], 19: [2, 13], 20: [2, 13], 22: [2, 13], 23: [2, 13], 24: [2, 13] }, { 5: [2, 16], 14: [2, 16], 15: [2, 16], 16: [2, 16], 19: [2, 16], 20: [2, 16], 22: [2, 16], 23: [2, 16], 24: [2, 16] }, { 5: [2, 17], 14: [2, 17], 15: [2, 17], 16: [2, 17], 19: [2, 17], 20: [2, 17], 22: [2, 17], 23: [2, 17], 24: [2, 17] }, { 5: [2, 18], 14: [2, 18], 15: [2, 18], 16: [2, 18], 19: [2, 18], 20: [2, 18], 22: [2, 18], 23: [2, 18], 24: [2, 18] }, { 18: [1, 59] }, { 18: [1, 60] }, { 18: [2, 21] }, { 18: [2, 25], 28: [2, 25], 29: [2, 25], 30: [2, 25], 33: [2, 25] }, { 18: [2, 32], 33: [2, 32] }, { 34: [1, 57] }, { 21: 61, 28: [1, 62], 29: [1, 63], 30: [1, 64], 33: [1, 25], 35: 24 }, { 18: [2, 39], 28: [2, 39], 29: [2, 39], 30: [2, 39], 33: [2, 39], 36: [2, 39] }, { 5: [2, 19], 14: [2, 19], 15: [2, 19], 16: [2, 19], 19: [2, 19], 20: [2, 19], 22: [2, 19], 23: [2, 19], 24: [2, 19] }, { 5: [2, 15], 14: [2, 15], 15: [2, 15], 16: [2, 15], 19: [2, 15], 20: [2, 15], 22: [2, 15], 23: [2, 15], 24: [2, 15] }, { 18: [2, 34], 33: [2, 34] }, { 18: [2, 35], 33: [2, 35] }, { 18: [2, 36], 33: [2, 36] }, { 18: [2, 37], 33: [2, 37]}],
            defaultActions: { 16: [2, 1], 37: [2, 23], 53: [2, 21] },
            parseError: function parseError(str, hash) {
                throw new Error(str);
            },
            parse: function parse(input) {
                var self = this, stack = [0], vstack = [null], lstack = [], table = this.table, yytext = "", yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1;
                this.lexer.setInput(input);
                this.lexer.yy = this.yy;
                this.yy.lexer = this.lexer;
                if (typeof this.lexer.yylloc == "undefined")
                    this.lexer.yylloc = {};
                var yyloc = this.lexer.yylloc;
                lstack.push(yyloc);
                if (typeof this.yy.parseError === "function")
                    this.parseError = this.yy.parseError;
                function popStack(n) {
                    stack.length = stack.length - 2 * n;
                    vstack.length = vstack.length - n;
                    lstack.length = lstack.length - n;
                }
                function lex() {
                    var token;
                    token = self.lexer.lex() || 1;
                    if (typeof token !== "number") {
                        token = self.symbols_[token] || token;
                    }
                    return token;
                }
                var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected;
                while (true) {
                    state = stack[stack.length - 1];
                    if (this.defaultActions[state]) {
                        action = this.defaultActions[state];
                    } else {
                        if (symbol == null)
                            symbol = lex();
                        action = table[state] && table[state][symbol];
                    }
                    if (typeof action === "undefined" || !action.length || !action[0]) {
                        if (!recovering) {
                            expected = [];
                            for (p in table[state])
                                if (this.terminals_[p] && p > 2) {
                                    expected.push("'" + this.terminals_[p] + "'");
                                }
                            var errStr = "";
                            if (this.lexer.showPosition) {
                                errStr = "Parse error on line " + (yylineno + 1) + ":\n" + this.lexer.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + this.terminals_[symbol] + "'";
                            } else {
                                errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == 1 ? "end of input" : "'" + (this.terminals_[symbol] || symbol) + "'");
                            }
                            this.parseError(errStr, { text: this.lexer.match, token: this.terminals_[symbol] || symbol, line: this.lexer.yylineno, loc: yyloc, expected: expected });
                        }
                    }
                    if (action[0] instanceof Array && action.length > 1) {
                        throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol);
                    }
                    switch (action[0]) {
                        case 1:
                            stack.push(symbol);
                            vstack.push(this.lexer.yytext);
                            lstack.push(this.lexer.yylloc);
                            stack.push(action[1]);
                            symbol = null;
                            if (!preErrorSymbol) {
                                yyleng = this.lexer.yyleng;
                                yytext = this.lexer.yytext;
                                yylineno = this.lexer.yylineno;
                                yyloc = this.lexer.yylloc;
                                if (recovering > 0)
                                    recovering--;
                            } else {
                                symbol = preErrorSymbol;
                                preErrorSymbol = null;
                            }
                            break;
                        case 2:
                            len = this.productions_[action[1]][1];
                            yyval.$ = vstack[vstack.length - len];
                            yyval._$ = { first_line: lstack[lstack.length - (len || 1)].first_line, last_line: lstack[lstack.length - 1].last_line, first_column: lstack[lstack.length - (len || 1)].first_column, last_column: lstack[lstack.length - 1].last_column };
                            r = this.performAction.call(yyval, yytext, yyleng, yylineno, this.yy, action[1], vstack, lstack);
                            if (typeof r !== "undefined") {
                                return r;
                            }
                            if (len) {
                                stack = stack.slice(0, -1 * len * 2);
                                vstack = vstack.slice(0, -1 * len);
                                lstack = lstack.slice(0, -1 * len);
                            }
                            stack.push(this.productions_[action[1]][0]);
                            vstack.push(yyval.$);
                            lstack.push(yyval._$);
                            newState = table[stack[stack.length - 2]][stack[stack.length - 1]];
                            stack.push(newState);
                            break;
                        case 3:
                            return true;
                    }
                }
                return true;
            }
        }; /* Jison generated lexer */
        var lexer = (function () {

            var lexer = ({ EOF: 1,
                parseError: function parseError(str, hash) {
                    if (this.yy.parseError) {
                        this.yy.parseError(str, hash);
                    } else {
                        throw new Error(str);
                    }
                },
                setInput: function (input) {
                    this._input = input;
                    this._more = this._less = this.done = false;
                    this.yylineno = this.yyleng = 0;
                    this.yytext = this.matched = this.match = '';
                    this.conditionStack = ['INITIAL'];
                    this.yylloc = { first_line: 1, first_column: 0, last_line: 1, last_column: 0 };
                    return this;
                },
                input: function () {
                    var ch = this._input[0];
                    this.yytext += ch;
                    this.yyleng++;
                    this.match += ch;
                    this.matched += ch;
                    var lines = ch.match(/\n/);
                    if (lines) this.yylineno++;
                    this._input = this._input.slice(1);
                    return ch;
                },
                unput: function (ch) {
                    this._input = ch + this._input;
                    return this;
                },
                more: function () {
                    this._more = true;
                    return this;
                },
                pastInput: function () {
                    var past = this.matched.substr(0, this.matched.length - this.match.length);
                    return (past.length > 20 ? '...' : '') + past.substr(-20).replace(/\n/g, "");
                },
                upcomingInput: function () {
                    var next = this.match;
                    if (next.length < 20) {
                        next += this._input.substr(0, 20 - next.length);
                    }
                    return (next.substr(0, 20) + (next.length > 20 ? '...' : '')).replace(/\n/g, "");
                },
                showPosition: function () {
                    var pre = this.pastInput();
                    var c = new Array(pre.length + 1).join("-");
                    return pre + this.upcomingInput() + "\n" + c + "^";
                },
                next: function () {
                    if (this.done) {
                        return this.EOF;
                    }
                    if (!this._input) this.done = true;

                    var token,
            match,
            col,
            lines;
                    if (!this._more) {
                        this.yytext = '';
                        this.match = '';
                    }
                    var rules = this._currentRules();
                    for (var i = 0; i < rules.length; i++) {
                        match = this._input.match(this.rules[rules[i]]);
                        if (match) {
                            lines = match[0].match(/\n.*/g);
                            if (lines) this.yylineno += lines.length;
                            this.yylloc = { first_line: this.yylloc.last_line,
                                last_line: this.yylineno + 1,
                                first_column: this.yylloc.last_column,
                                last_column: lines ? lines[lines.length - 1].length - 1 : this.yylloc.last_column + match[0].length
                            }
                            this.yytext += match[0];
                            this.match += match[0];
                            this.matches = match;
                            this.yyleng = this.yytext.length;
                            this._more = false;
                            this._input = this._input.slice(match[0].length);
                            this.matched += match[0];
                            token = this.performAction.call(this, this.yy, this, rules[i], this.conditionStack[this.conditionStack.length - 1]);
                            if (token) return token;
                            else return;
                        }
                    }
                    if (this._input === "") {
                        return this.EOF;
                    } else {
                        this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. Unrecognized text.\n' + this.showPosition(),
                    { text: "", token: null, line: this.yylineno });
                    }
                },
                lex: function lex() {
                    var r = this.next();
                    if (typeof r !== 'undefined') {
                        return r;
                    } else {
                        return this.lex();
                    }
                },
                begin: function begin(condition) {
                    this.conditionStack.push(condition);
                },
                popState: function popState() {
                    return this.conditionStack.pop();
                },
                _currentRules: function _currentRules() {
                    return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules;
                },
                topState: function () {
                    return this.conditionStack[this.conditionStack.length - 2];
                },
                pushState: function begin(condition) {
                    this.begin(condition);
                } 
            });
            lexer.performAction = function anonymous(yy, yy_, $avoiding_name_collisions, YY_START) {

                var YYSTATE = YY_START
                switch ($avoiding_name_collisions) {
                    case 0:
                        if (yy_.yytext.slice(-1) !== "\\") this.begin("mu");
                        if (yy_.yytext.slice(-1) === "\\") yy_.yytext = yy_.yytext.substr(0, yy_.yyleng - 1), this.begin("emu");
                        if (yy_.yytext) return 14;

                        break;
                    case 1: return 14;
                        break;
                    case 2: this.popState(); return 14;
                        break;
                    case 3: return 24;
                        break;
                    case 4: return 16;
                        break;
                    case 5: return 20;
                        break;
                    case 6: return 19;
                        break;
                    case 7: return 19;
                        break;
                    case 8: return 23;
                        break;
                    case 9: return 23;
                        break;
                    case 10: yy_.yytext = yy_.yytext.substr(3, yy_.yyleng - 5); this.popState(); return 15;
                        break;
                    case 11: return 22;
                        break;
                    case 12: return 34;
                        break;
                    case 13: return 33;
                        break;
                    case 14: return 33;
                        break;
                    case 15: return 36;
                        break;
                    case 16: /*ignore whitespace*/
                        break;
                    case 17: this.popState(); return 18;
                        break;
                    case 18: this.popState(); return 18;
                        break;
                    case 19: yy_.yytext = yy_.yytext.substr(1, yy_.yyleng - 2).replace(/\\"/g, '"'); return 28;
                        break;
                    case 20: return 30;
                        break;
                    case 21: return 30;
                        break;
                    case 22: return 29;
                        break;
                    case 23: return 33;
                        break;
                    case 24: yy_.yytext = yy_.yytext.substr(1, yy_.yyleng - 2); return 33;
                        break;
                    case 25: return 'INVALID';
                        break;
                    case 26: return 5;
                        break;
                }
            };
            lexer.rules = [/^[^\x00]*?(?=(\{\{))/, /^[^\x00]+/, /^[^\x00]{2,}?(?=(\{\{))/, /^\{\{>/, /^\{\{#/, /^\{\{\//, /^\{\{\^/, /^\{\{\s*else\b/, /^\{\{\{/, /^\{\{&/, /^\{\{![\s\S]*?\}\}/, /^\{\{/, /^=/, /^\.(?=[} ])/, /^\.\./, /^[\/.]/, /^\s+/, /^\}\}\}/, /^\}\}/, /^"(\\["]|[^"])*"/, /^true(?=[}\s])/, /^false(?=[}\s])/, /^[0-9]+(?=[}\s])/, /^[a-zA-Z0-9_$-]+(?=[=}\s\/.])/, /^\[[^\]]*\]/, /^./, /^$/];
            lexer.conditions = { "mu": { "rules": [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26], "inclusive": false }, "emu": { "rules": [2], "inclusive": false }, "INITIAL": { "rules": [0, 1, 26], "inclusive": true} }; return lexer;
        })()
        parser.lexer = lexer;
        return parser;
    })();

    // lib/handlebars/compiler/base.js
    Handlebars.Parser = handlebars;

    Handlebars.parse = function (string) {
        Handlebars.Parser.yy = Handlebars.AST;
        return Handlebars.Parser.parse(string);
    };

    Handlebars.print = function (ast) {
        return new Handlebars.PrintVisitor().accept(ast);
    };

    Handlebars.logger = {
        DEBUG: 0, INFO: 1, WARN: 2, ERROR: 3, level: 3,

        // override in the host environment
        log: function (level, str) { }
    };

    Handlebars.log = function (level, str) { Handlebars.logger.log(level, str); };
    ;
    // lib/handlebars/compiler/ast.js
    (function () {

        Handlebars.AST = {};

        Handlebars.AST.ProgramNode = function (statements, inverse) {
            this.type = "program";
            this.statements = statements;
            if (inverse) { this.inverse = new Handlebars.AST.ProgramNode(inverse); }
        };

        Handlebars.AST.MustacheNode = function (params, hash, unescaped) {
            this.type = "mustache";
            this.id = params[0];
            this.params = params.slice(1);
            this.hash = hash;
            this.escaped = !unescaped;
        };

        Handlebars.AST.PartialNode = function (id, context) {
            this.type = "partial";

            // TODO: disallow complex IDs

            this.id = id;
            this.context = context;
        };

        var verifyMatch = function (open, close) {
            if (open.original !== close.original) {
                throw new Handlebars.Exception(open.original + " doesn't match " + close.original);
            }
        };

        Handlebars.AST.BlockNode = function (mustache, program, close) {
            verifyMatch(mustache.id, close);
            this.type = "block";
            this.mustache = mustache;
            this.program = program;
        };

        Handlebars.AST.InverseNode = function (mustache, program, close) {
            verifyMatch(mustache.id, close);
            this.type = "inverse";
            this.mustache = mustache;
            this.program = program;
        };

        Handlebars.AST.ContentNode = function (string) {
            this.type = "content";
            this.string = string;
        };

        Handlebars.AST.HashNode = function (pairs) {
            this.type = "hash";
            this.pairs = pairs;
        };

        Handlebars.AST.IdNode = function (parts) {
            this.type = "ID";
            this.original = parts.join(".");

            var dig = [], depth = 0;

            for (var i = 0, l = parts.length; i < l; i++) {
                var part = parts[i];

                if (part === "..") { depth++; }
                else if (part === "." || part === "this") { this.isScoped = true; }
                else { dig.push(part); }
            }

            this.parts = dig;
            this.string = dig.join('.');
            this.depth = depth;
            this.isSimple = (dig.length === 1) && (depth === 0);
        };

        Handlebars.AST.StringNode = function (string) {
            this.type = "STRING";
            this.string = string;
        };

        Handlebars.AST.IntegerNode = function (integer) {
            this.type = "INTEGER";
            this.integer = integer;
        };

        Handlebars.AST.BooleanNode = function (bool) {
            this.type = "BOOLEAN";
            this.bool = bool;
        };

        Handlebars.AST.CommentNode = function (comment) {
            this.type = "comment";
            this.comment = comment;
        };

    })(); ;
    //>>excludeEnd('excludeHbsParser')
    // lib/handlebars/utils.js
    Handlebars.Exception = function (message) {
        var tmp = Error.prototype.constructor.apply(this, arguments);

        for (var p in tmp) {
            if (tmp.hasOwnProperty(p)) { this[p] = tmp[p]; }
        }

        this.message = tmp.message;
    };
    Handlebars.Exception.prototype = new Error;

    // Build out our basic SafeString type
    Handlebars.SafeString = function (string) {
        this.string = string;
    };
    Handlebars.SafeString.prototype.toString = function () {
        return this.string.toString();
    };

    (function () {
        var escape = {
            "<": "&lt;",
            ">": "&gt;",
            '"': "&quot;",
            "'": "&#x27;",
            "`": "&#x60;"
        };

        var badChars = /&(?!\w+;)|[<>"'`]/g;
        var possible = /[&<>"'`]/;

        var escapeChar = function (chr) {
            return escape[chr] || "&amp;";
        };

        Handlebars.Utils = {
            escapeExpression: function (string) {
                // don't escape SafeStrings, since they're already safe
                if (string instanceof Handlebars.SafeString) {
                    return string.toString();
                } else if (string == null || string === false) {
                    return "";
                }

                if (!possible.test(string)) { return string; }
                return string.replace(badChars, escapeChar);
            },

            isEmpty: function (value) {
                if (typeof value === "undefined") {
                    return true;
                } else if (value === null) {
                    return true;
                } else if (value === false) {
                    return true;
                } else if (Object.prototype.toString.call(value) === "[object Array]" && value.length === 0) {
                    return true;
                } else {
                    return false;
                }
            }
        };
    })(); ;
    // lib/handlebars/compiler/compiler.js
    Handlebars.Compiler = function () { };
    Handlebars.JavaScriptCompiler = function () { };

    (function (Compiler, JavaScriptCompiler) {
        Compiler.OPCODE_MAP = {
            appendContent: 1,
            getContext: 2,
            lookupWithHelpers: 3,
            lookup: 4,
            append: 5,
            invokeMustache: 6,
            appendEscaped: 7,
            pushString: 8,
            truthyOrFallback: 9,
            functionOrFallback: 10,
            invokeProgram: 11,
            invokePartial: 12,
            push: 13,
            assignToHash: 15,
            pushStringParam: 16
        };

        Compiler.MULTI_PARAM_OPCODES = {
            appendContent: 1,
            getContext: 1,
            lookupWithHelpers: 2,
            lookup: 1,
            invokeMustache: 3,
            pushString: 1,
            truthyOrFallback: 1,
            functionOrFallback: 1,
            invokeProgram: 3,
            invokePartial: 1,
            push: 1,
            assignToHash: 1,
            pushStringParam: 1
        };

        Compiler.DISASSEMBLE_MAP = {};

        for (var prop in Compiler.OPCODE_MAP) {
            var value = Compiler.OPCODE_MAP[prop];
            Compiler.DISASSEMBLE_MAP[value] = prop;
        }

        Compiler.multiParamSize = function (code) {
            return Compiler.MULTI_PARAM_OPCODES[Compiler.DISASSEMBLE_MAP[code]];
        };

        Compiler.prototype = {
            compiler: Compiler,

            disassemble: function () {
                var opcodes = this.opcodes, opcode, nextCode;
                var out = [], str, name, value;

                for (var i = 0, l = opcodes.length; i < l; i++) {
                    opcode = opcodes[i];

                    if (opcode === 'DECLARE') {
                        name = opcodes[++i];
                        value = opcodes[++i];
                        out.push("DECLARE " + name + " = " + value);
                    } else {
                        str = Compiler.DISASSEMBLE_MAP[opcode];

                        var extraParams = Compiler.multiParamSize(opcode);
                        var codes = [];

                        for (var j = 0; j < extraParams; j++) {
                            nextCode = opcodes[++i];

                            if (typeof nextCode === "string") {
                                nextCode = "\"" + nextCode.replace("\n", "\\n") + "\"";
                            }

                            codes.push(nextCode);
                        }

                        str = str + " " + codes.join(" ");

                        out.push(str);
                    }
                }

                return out.join("\n");
            },

            guid: 0,

            compile: function (program, options) {
                this.children = [];
                this.depths = { list: [] };
                this.options = options;

                // These changes will propagate to the other compiler components
                var knownHelpers = this.options.knownHelpers;
                this.options.knownHelpers = {
                    'helperMissing': true,
                    'blockHelperMissing': true,
                    'each': true,
                    'if': true,
                    'unless': true,
                    'with': true,
                    'log': true
                };
                if (knownHelpers) {
                    for (var name in knownHelpers) {
                        this.options.knownHelpers[name] = knownHelpers[name];
                    }
                }

                return this.program(program);
            },

            accept: function (node) {
                return this[node.type](node);
            },

            program: function (program) {
                var statements = program.statements, statement;
                this.opcodes = [];

                for (var i = 0, l = statements.length; i < l; i++) {
                    statement = statements[i];
                    this[statement.type](statement);
                }
                this.isSimple = l === 1;

                this.depths.list = this.depths.list.sort(function (a, b) {
                    return a - b;
                });

                return this;
            },

            compileProgram: function (program) {
                var result = new this.compiler().compile(program, this.options);
                var guid = this.guid++;

                this.usePartial = this.usePartial || result.usePartial;

                this.children[guid] = result;

                for (var i = 0, l = result.depths.list.length; i < l; i++) {
                    depth = result.depths.list[i];

                    if (depth < 2) { continue; }
                    else { this.addDepth(depth - 1); }
                }

                return guid;
            },

            block: function (block) {
                var mustache = block.mustache;
                var depth, child, inverse, inverseGuid;

                var params = this.setupStackForMustache(mustache);

                var programGuid = this.compileProgram(block.program);

                if (block.program.inverse) {
                    inverseGuid = this.compileProgram(block.program.inverse);
                    this.declare('inverse', inverseGuid);
                }

                this.opcode('invokeProgram', programGuid, params.length, !!mustache.hash);
                this.declare('inverse', null);
                this.opcode('append');
            },

            inverse: function (block) {
                var params = this.setupStackForMustache(block.mustache);

                var programGuid = this.compileProgram(block.program);

                this.declare('inverse', programGuid);

                this.opcode('invokeProgram', null, params.length, !!block.mustache.hash);
                this.declare('inverse', null);
                this.opcode('append');
            },

            hash: function (hash) {
                var pairs = hash.pairs, pair, val;

                this.opcode('push', '{}');

                for (var i = 0, l = pairs.length; i < l; i++) {
                    pair = pairs[i];
                    val = pair[1];

                    this.accept(val);
                    this.opcode('assignToHash', pair[0]);
                }
            },

            partial: function (partial) {
                var id = partial.id;
                this.usePartial = true;

                if (partial.context) {
                    this.ID(partial.context);
                } else {
                    this.opcode('push', 'depth0');
                }

                this.opcode('invokePartial', id.original);
                this.opcode('append');
            },

            content: function (content) {
                this.opcode('appendContent', content.string);
            },

            mustache: function (mustache) {
                var params = this.setupStackForMustache(mustache);

                this.opcode('invokeMustache', params.length, mustache.id.original, !!mustache.hash);

                if (mustache.escaped && !this.options.noEscape) {
                    this.opcode('appendEscaped');
                } else {
                    this.opcode('append');
                }
            },

            ID: function (id) {
                this.addDepth(id.depth);

                this.opcode('getContext', id.depth);

                this.opcode('lookupWithHelpers', id.parts[0] || null, id.isScoped || false);

                for (var i = 1, l = id.parts.length; i < l; i++) {
                    this.opcode('lookup', id.parts[i]);
                }
            },

            STRING: function (string) {
                this.opcode('pushString', string.string);
            },

            INTEGER: function (integer) {
                this.opcode('push', integer.integer);
            },

            BOOLEAN: function (bool) {
                this.opcode('push', bool.bool);
            },

            comment: function () { },

            // HELPERS
            pushParams: function (params) {
                var i = params.length, param;

                while (i--) {
                    param = params[i];

                    if (this.options.stringParams) {
                        if (param.depth) {
                            this.addDepth(param.depth);
                        }

                        this.opcode('getContext', param.depth || 0);
                        this.opcode('pushStringParam', param.string);
                    } else {
                        this[param.type](param);
                    }
                }
            },

            opcode: function (name, val1, val2, val3) {
                this.opcodes.push(Compiler.OPCODE_MAP[name]);
                if (val1 !== undefined) { this.opcodes.push(val1); }
                if (val2 !== undefined) { this.opcodes.push(val2); }
                if (val3 !== undefined) { this.opcodes.push(val3); }
            },

            declare: function (name, value) {
                this.opcodes.push('DECLARE');
                this.opcodes.push(name);
                this.opcodes.push(value);
            },

            addDepth: function (depth) {
                if (depth === 0) { return; }

                if (!this.depths[depth]) {
                    this.depths[depth] = true;
                    this.depths.list.push(depth);
                }
            },

            setupStackForMustache: function (mustache) {
                var params = mustache.params;

                this.pushParams(params);

                if (mustache.hash) {
                    this.hash(mustache.hash);
                }

                this.ID(mustache.id);

                return params;
            }
        };

        JavaScriptCompiler.prototype = {
            // PUBLIC API: You can override these methods in a subclass to provide
            // alternative compiled forms for name lookup and buffering semantics
            nameLookup: function (parent, name, type) {
                if (/^[0-9]+$/.test(name)) {
                    return parent + "[" + name + "]";
                } else if (JavaScriptCompiler.isValidJavaScriptVariableName(name)) {
                    return parent + "." + name;
                }
                else {
                    return parent + "['" + name + "']";
                }
            },

            appendToBuffer: function (string) {
                if (this.environment.isSimple) {
                    return "return " + string + ";";
                } else {
                    return "buffer += " + string + ";";
                }
            },

            initializeBuffer: function () {
                return this.quotedString("");
            },

            namespace: "Handlebars",
            // END PUBLIC API

            compile: function (environment, options, context, asObject) {
                this.environment = environment;
                this.options = options || {};

                this.name = this.environment.name;
                this.isChild = !!context;
                this.context = context || {
                    programs: [],
                    aliases: { self: 'this' },
                    registers: { list: [] }
                };

                this.preamble();

                this.stackSlot = 0;
                this.stackVars = [];

                this.compileChildren(environment, options);

                var opcodes = environment.opcodes, opcode;

                this.i = 0;

                for (l = opcodes.length; this.i < l; this.i++) {
                    opcode = this.nextOpcode(0);

                    if (opcode[0] === 'DECLARE') {
                        this.i = this.i + 2;
                        this[opcode[1]] = opcode[2];
                    } else {
                        this.i = this.i + opcode[1].length;
                        this[opcode[0]].apply(this, opcode[1]);
                    }
                }

                return this.createFunctionContext(asObject);
            },

            nextOpcode: function (n) {
                var opcodes = this.environment.opcodes, opcode = opcodes[this.i + n], name, val;
                var extraParams, codes;

                if (opcode === 'DECLARE') {
                    name = opcodes[this.i + 1];
                    val = opcodes[this.i + 2];
                    return ['DECLARE', name, val];
                } else {
                    name = Compiler.DISASSEMBLE_MAP[opcode];

                    extraParams = Compiler.multiParamSize(opcode);
                    codes = [];

                    for (var j = 0; j < extraParams; j++) {
                        codes.push(opcodes[this.i + j + 1 + n]);
                    }

                    return [name, codes];
                }
            },

            eat: function (opcode) {
                this.i = this.i + opcode.length;
            },

            preamble: function () {
                var out = [];

                // this register will disambiguate helper lookup from finding a function in
                // a context. This is necessary for mustache compatibility, which requires
                // that context functions in blocks are evaluated by blockHelperMissing, and
                // then proceed as if the resulting value was provided to blockHelperMissing.
                this.useRegister('foundHelper');

                if (!this.isChild) {
                    var namespace = this.namespace;
                    var copies = "helpers = helpers || " + namespace + ".helpers;";
                    if (this.environment.usePartial) { copies = copies + " partials = partials || " + namespace + ".partials;"; }
                    out.push(copies);
                } else {
                    out.push('');
                }

                if (!this.environment.isSimple) {
                    out.push(", buffer = " + this.initializeBuffer());
                } else {
                    out.push("");
                }

                // track the last context pushed into place to allow skipping the
                // getContext opcode when it would be a noop
                this.lastContext = 0;
                this.source = out;
            },

            createFunctionContext: function (asObject) {
                var locals = this.stackVars;
                if (!this.isChild) {
                    locals = locals.concat(this.context.registers.list);
                }

                if (locals.length > 0) {
                    this.source[1] = this.source[1] + ", " + locals.join(", ");
                }

                // Generate minimizer alias mappings
                if (!this.isChild) {
                    var aliases = []
                    for (var alias in this.context.aliases) {
                        this.source[1] = this.source[1] + ', ' + alias + '=' + this.context.aliases[alias];
                    }
                }

                if (this.source[1]) {
                    this.source[1] = "var " + this.source[1].substring(2) + ";";
                }

                // Merge children
                if (!this.isChild) {
                    this.source[1] += '\n' + this.context.programs.join('\n') + '\n';
                }

                if (!this.environment.isSimple) {
                    this.source.push("return buffer;");
                }

                var params = this.isChild ? ["depth0", "data"] : ["Handlebars", "depth0", "helpers", "partials", "data"];

                for (var i = 0, l = this.environment.depths.list.length; i < l; i++) {
                    params.push("depth" + this.environment.depths.list[i]);
                }

                if (asObject) {
                    params.push(this.source.join("\n  "));

                    return Function.apply(this, params);
                } else {
                    var functionSource = 'function ' + (this.name || '') + '(' + params.join(',') + ') {\n  ' + this.source.join("\n  ") + '}';
                    Handlebars.log(Handlebars.logger.DEBUG, functionSource + "\n\n");
                    return functionSource;
                }
            },

            appendContent: function (content) {
                this.source.push(this.appendToBuffer(this.quotedString(content)));
            },

            append: function () {
                var local = this.popStack();
                this.source.push("if(" + local + " || " + local + " === 0) { " + this.appendToBuffer(local) + " }");
                if (this.environment.isSimple) {
                    this.source.push("else { " + this.appendToBuffer("''") + " }");
                }
            },

            appendEscaped: function () {
                var opcode = this.nextOpcode(1), extra = "";
                this.context.aliases.escapeExpression = 'this.escapeExpression';

                if (opcode[0] === 'appendContent') {
                    extra = " + " + this.quotedString(opcode[1][0]);
                    this.eat(opcode);
                }

                this.source.push(this.appendToBuffer("escapeExpression(" + this.popStack() + ")" + extra));
            },

            getContext: function (depth) {
                if (this.lastContext !== depth) {
                    this.lastContext = depth;
                }
            },

            lookupWithHelpers: function (name, isScoped) {
                if (name) {
                    var topStack = this.nextStack();

                    this.usingKnownHelper = false;

                    var toPush;
                    if (!isScoped && this.options.knownHelpers[name]) {
                        toPush = topStack + " = " + this.nameLookup('helpers', name, 'helper');
                        this.usingKnownHelper = true;
                    } else if (isScoped || this.options.knownHelpersOnly) {
                        toPush = topStack + " = " + this.nameLookup('depth' + this.lastContext, name, 'context');
                    } else {
                        this.register('foundHelper', this.nameLookup('helpers', name, 'helper'));
                        toPush = topStack + " = foundHelper || " + this.nameLookup('depth' + this.lastContext, name, 'context');
                    }

                    toPush += ';';
                    this.source.push(toPush);
                } else {
                    this.pushStack('depth' + this.lastContext);
                }
            },

            lookup: function (name) {
                var topStack = this.topStack();
                this.source.push(topStack + " = (" + topStack + " === null || " + topStack + " === undefined || " + topStack + " === false ? " +
 				topStack + " : " + this.nameLookup(topStack, name, 'context') + ");");
            },

            pushStringParam: function (string) {
                this.pushStack('depth' + this.lastContext);
                this.pushString(string);
            },

            pushString: function (string) {
                this.pushStack(this.quotedString(string));
            },

            push: function (name) {
                this.pushStack(name);
            },

            invokeMustache: function (paramSize, original, hasHash) {
                this.populateParams(paramSize, this.quotedString(original), "{}", null, hasHash, function (nextStack, helperMissingString, id) {
                    if (!this.usingKnownHelper) {
                        this.context.aliases.helperMissing = 'helpers.helperMissing';
                        this.context.aliases.undef = 'void 0';
                        this.source.push("else if(" + id + "=== undef) { " + nextStack + " = helperMissing.call(" + helperMissingString + "); }");
                        if (nextStack !== id) {
                            this.source.push("else { " + nextStack + " = " + id + "; }");
                        }
                    }
                });
            },

            invokeProgram: function (guid, paramSize, hasHash) {
                var inverse = this.programExpression(this.inverse);
                var mainProgram = this.programExpression(guid);

                this.populateParams(paramSize, null, mainProgram, inverse, hasHash, function (nextStack, helperMissingString, id) {
                    if (!this.usingKnownHelper) {
                        this.context.aliases.blockHelperMissing = 'helpers.blockHelperMissing';
                        this.source.push("else { " + nextStack + " = blockHelperMissing.call(" + helperMissingString + "); }");
                    }
                });
            },

            populateParams: function (paramSize, helperId, program, inverse, hasHash, fn) {
                var needsRegister = hasHash || this.options.stringParams || inverse || this.options.data;
                var id = this.popStack(), nextStack;
                var params = [], param, stringParam, stringOptions;

                if (needsRegister) {
                    this.register('tmp1', program);
                    stringOptions = 'tmp1';
                } else {
                    stringOptions = '{ hash: {} }';
                }

                if (needsRegister) {
                    var hash = (hasHash ? this.popStack() : '{}');
                    this.source.push('tmp1.hash = ' + hash + ';');
                }

                if (this.options.stringParams) {
                    this.source.push('tmp1.contexts = [];');
                }

                for (var i = 0; i < paramSize; i++) {
                    param = this.popStack();
                    params.push(param);

                    if (this.options.stringParams) {
                        this.source.push('tmp1.contexts.push(' + this.popStack() + ');');
                    }
                }

                if (inverse) {
                    this.source.push('tmp1.fn = tmp1;');
                    this.source.push('tmp1.inverse = ' + inverse + ';');
                }

                if (this.options.data) {
                    this.source.push('tmp1.data = data;');
                }

                params.push(stringOptions);

                this.populateCall(params, id, helperId || id, fn, program !== '{}');
            },

            populateCall: function (params, id, helperId, fn, program) {
                var paramString = ["depth0"].concat(params).join(", ");
                var helperMissingString = ["depth0"].concat(helperId).concat(params).join(", ");

                var nextStack = this.nextStack();

                if (this.usingKnownHelper) {
                    this.source.push(nextStack + " = " + id + ".call(" + paramString + ");");
                } else {
                    this.context.aliases.functionType = '"function"';
                    var condition = program ? "foundHelper && " : ""
                    this.source.push("if(" + condition + "typeof " + id + " === functionType) { " + nextStack + " = " + id + ".call(" + paramString + "); }");
                }
                fn.call(this, nextStack, helperMissingString, id);
                this.usingKnownHelper = false;
            },

            invokePartial: function (context) {
                params = [this.nameLookup('partials', context, 'partial'), "'" + context + "'", this.popStack(), "helpers", "partials"];

                if (this.options.data) {
                    params.push("data");
                }

                this.pushStack("self.invokePartial(" + params.join(", ") + ");");
            },

            assignToHash: function (key) {
                var value = this.popStack();
                var hash = this.topStack();

                this.source.push(hash + "['" + key + "'] = " + value + ";");
            },

            // HELPERS

            compiler: JavaScriptCompiler,

            compileChildren: function (environment, options) {
                var children = environment.children, child, compiler;

                for (var i = 0, l = children.length; i < l; i++) {
                    child = children[i];
                    compiler = new this.compiler();

                    this.context.programs.push('');     // Placeholder to prevent name conflicts for nested children
                    var index = this.context.programs.length;
                    child.index = index;
                    child.name = 'program' + index;
                    this.context.programs[index] = compiler.compile(child, options, this.context);
                }
            },

            programExpression: function (guid) {
                if (guid == null) { return "self.noop"; }

                var child = this.environment.children[guid],
          depths = child.depths.list;
                var programParams = [child.index, child.name, "data"];

                for (var i = 0, l = depths.length; i < l; i++) {
                    depth = depths[i];

                    if (depth === 1) { programParams.push("depth0"); }
                    else { programParams.push("depth" + (depth - 1)); }
                }

                if (depths.length === 0) {
                    return "self.program(" + programParams.join(", ") + ")";
                } else {
                    programParams.shift();
                    return "self.programWithDepth(" + programParams.join(", ") + ")";
                }
            },

            register: function (name, val) {
                this.useRegister(name);
                this.source.push(name + " = " + val + ";");
            },

            useRegister: function (name) {
                if (!this.context.registers[name]) {
                    this.context.registers[name] = true;
                    this.context.registers.list.push(name);
                }
            },

            pushStack: function (item) {
                this.source.push(this.nextStack() + " = " + item + ";");
                return "stack" + this.stackSlot;
            },

            nextStack: function () {
                this.stackSlot++;
                if (this.stackSlot > this.stackVars.length) { this.stackVars.push("stack" + this.stackSlot); }
                return "stack" + this.stackSlot;
            },

            popStack: function () {
                return "stack" + this.stackSlot--;
            },

            topStack: function () {
                return "stack" + this.stackSlot;
            },

            quotedString: function (str) {
                return '"' + str
        .replace(/\\/g, '\\\\')
        .replace(/"/g, '\\"')
        .replace(/\n/g, '\\n')
        .replace(/\r/g, '\\r') + '"';
            }
        };

        var reservedWords = (
    "break else new var" +
    " case finally return void" +
    " catch for switch while" +
    " continue function this with" +
    " default if throw" +
    " delete in try" +
    " do instanceof typeof" +
    " abstract enum int short" +
    " boolean export interface static" +
    " byte extends long super" +
    " char final native synchronized" +
    " class float package throws" +
    " const goto private transient" +
    " debugger implements protected volatile" +
    " double import public let yield"
  ).split(" ");

        var compilerWords = JavaScriptCompiler.RESERVED_WORDS = {};

        for (var i = 0, l = reservedWords.length; i < l; i++) {
            compilerWords[reservedWords[i]] = true;
        }

        JavaScriptCompiler.isValidJavaScriptVariableName = function (name) {
            if (!JavaScriptCompiler.RESERVED_WORDS[name] && /^[a-zA-Z_$][0-9a-zA-Z_$]+$/.test(name)) {
                return true;
            }
            return false;
        }

    })(Handlebars.Compiler, Handlebars.JavaScriptCompiler);
    //>>excludeStart('excludeHbsParser', pragmas.excludeHbsParser)
    Handlebars.precompile = function (string, options) {
        options = options || {};

        var ast = Handlebars.parse(string);
        var environment = new Handlebars.Compiler().compile(ast, options);
        return new Handlebars.JavaScriptCompiler().compile(environment, options);
    };

    Handlebars.compile = function (string, options) {
        options = options || {};

        var compiled;
        function compile() {
            var ast = Handlebars.parse(string);
            var environment = new Handlebars.Compiler().compile(ast, options);
            var templateSpec = new Handlebars.JavaScriptCompiler().compile(environment, options, undefined, true);
            return Handlebars.template(templateSpec);
        }

        // Template is only compiled on first use and cached after that point.
        return function (context, options) {
            if (!compiled) {
                compiled = compile();
            }
            return compiled.call(this, context, options);
        };
    };
    //>>excludeEnd('excludeHbsParser')
    ;
    // lib/handlebars/runtime.js
    Handlebars.VM = {
        template: function (templateSpec) {
            // Just add water
            var container = {
                escapeExpression: Handlebars.Utils.escapeExpression,
                invokePartial: Handlebars.VM.invokePartial,
                programs: [],
                program: function (i, fn, data) {
                    var programWrapper = this.programs[i];
                    if (data) {
                        return Handlebars.VM.program(fn, data);
                    } else if (programWrapper) {
                        return programWrapper;
                    } else {
                        programWrapper = this.programs[i] = Handlebars.VM.program(fn);
                        return programWrapper;
                    }
                },
                programWithDepth: Handlebars.VM.programWithDepth,
                noop: Handlebars.VM.noop
            };

            return function (context, options) {
                options = options || {};
                return templateSpec.call(container, Handlebars, context, options.helpers, options.partials, options.data);
            };
        },

        programWithDepth: function (fn, data, $depth) {
            var args = Array.prototype.slice.call(arguments, 2);

            return function (context, options) {
                options = options || {};

                return fn.apply(this, [context, options.data || data].concat(args));
            };
        },
        program: function (fn, data) {
            return function (context, options) {
                options = options || {};

                return fn(context, options.data || data);
            };
        },
        noop: function () { return ""; },
        invokePartial: function (partial, name, context, helpers, partials, data) {
            options = { helpers: helpers, partials: partials, data: data };

            if (partial === undefined) {
                throw new Handlebars.Exception("The partial " + name + " could not be found");
            } else if (partial instanceof Function) {
                return partial(context, options);
            } else if (!Handlebars.compile) {
                throw new Handlebars.Exception("The partial " + name + " could not be compiled when running in runtime-only mode");
            } else {
                partials[name] = Handlebars.compile(partial);
                return partials[name](context, options);
            }
        }
    };

    Handlebars.template = Handlebars.VM.template;
    ;

    // AMD Define
    define(function () {
        return Handlebars;
    });

})();
